package controllers

import javax.inject.Inject
import dao._
import play.api.libs.json.Json
import play.api.mvc._
import models.Tables._
import org.apache.commons.math3.stat.StatUtils

import scala.concurrent.ExecutionContext.Implicits.global

class GenomeBrowseController @Inject()(cc:ControllerComponents, bgAnnoDao: BgAnnoDao,bgCdsDao: BgCdsDao,bgPepDao: BgPepDao,fpkmDao: FpkmDao,
                                       mrnaDao: GeneDao) extends AbstractController(cc) {

  def toIndex = Action {
    Ok(views.html.genome.browse.index())
  }

  def getAllBgAnnos = Action.async { implicit request =>
    bgAnnoDao.selectAll.map { x =>
      val array = getArrayByBgAnnos(x)
      Ok(Json.toJson(array))
    }
  }

  def getArrayByBgAnnos(x: Seq[BgannoRow]) = {
    x.map { y =>
      val geneIdStr = "<a target='_blank' title='more' href='" + routes.GenomeBrowseController.getDetailInfo(y.geneid) + "'>" + y.geneid + "</a>"
      Json.obj(
        "geneId" ->geneIdStr, "chr" -> y.chr, "start" -> y.start, "end" -> y.end, "dir" -> y.dir, "kegg" -> y.kegg,
        "ipr" -> y.ipr, "interPro" -> y.interpro, "goPlant" -> y.goplant, "keggPlant" -> y.keggplant, "nrId" -> y.nrid
      )
    }
  }

  def getDetailInfo(geneId: String) = Action.async { implicit request =>
    bgAnnoDao.selectByGeneId(geneId).map(_.get).zip(bgCdsDao.selectByGeneId(geneId).map(_.get)).
      zip(bgPepDao.selectByGeneId(geneId).map(_.get)).zip(mrnaDao.selectByGeneId(geneId)).
      map {case(((bgAnno,bgCds),bgPep),mrna)=>
      val x=(bgAnno,bgCds,bgPep,mrna)
      Ok(views.html.genome.browse.detailInfo(x))
    }
  }

  def boxPlotByGeneId(id: String) = Action.async { implicit request =>
    val fpkms = fpkmDao.selectByGeneId(id)
    fpkms.map(x => Ok {
      val typeX = x.groupBy(_.group)
      val typeLong = typeX.map {
        case (kind, longs) =>
          val values = longs.map(_.value).toArray
          val minValue = values.min
          val Q1 = StatUtils.percentile(values, 25)
          val Q2 = StatUtils.percentile(values, 50)
          val Q3 = StatUtils.percentile(values, 75)
          val maxValue = values.max
          Array(kind, minValue.toString, Q1.toString, Q2.toString, Q3.toString, maxValue.toString)
      }
      val jsons = Json.obj("ev" -> typeLong.map(_.drop(1).map(_.toDouble)), "tissue" -> typeLong.map(_ (0)))
      Json.toJson(jsons)
    })
  }



}
